package cn.wolfcode.business.service.impl;

import cn.wolfcode.business.domain.BusAppointment;
import cn.wolfcode.business.domain.BusStatement;
import cn.wolfcode.business.domain.BusStatementItem;
import cn.wolfcode.business.mapper.BusStatementItemMapper;
import cn.wolfcode.business.service.IBusAppointmentService;
import cn.wolfcode.business.service.IBusStatementItemService;
import cn.wolfcode.business.service.IBusStatementService;
import cn.wolfcode.business.vo.BusStatementItemVO;
import cn.wolfcode.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 结算单明细Service业务层处理
 * 
 * @author wolfcode
 * @date 2025-05-06
 */
@Service
public class BusStatementItemServiceImpl implements IBusStatementItemService 
{
    @Autowired
    private BusStatementItemMapper busStatementItemMapper;
    @Autowired
    private IBusStatementService statementService;
    @Autowired
    private IBusAppointmentService appointmentService;

    /**
     * 查询结算单明细
     * 
     * @param id 结算单明细主键
     * @return 结算单明细
     */
    @Override
    public BusStatementItem selectBusStatementItemById(Long id)
    {
        return busStatementItemMapper.selectBusStatementItemById(id);
    }

    /**
     * 查询结算单明细列表
     * 
     * @param busStatementItem 结算单明细
     * @return 结算单明细
     */
    @Override
    public List<BusStatementItem> selectBusStatementItemList(BusStatementItem busStatementItem)
    {
        return busStatementItemMapper.selectBusStatementItemList(busStatementItem);
    }

    /**
     * 新增结算单明细
     * 
     * @param busStatementItem 结算单明细
     * @return 结果
     */
    @Override
    public int insertBusStatementItem(BusStatementItem busStatementItem)
    {
        return busStatementItemMapper.insertBusStatementItem(busStatementItem);
    }

    /**
     * 修改结算单明细
     * 
     * @param busStatementItem 结算单明细
     * @return 结果
     */
    @Override
    public int updateBusStatementItem(BusStatementItem busStatementItem)
    {
        return busStatementItemMapper.updateBusStatementItem(busStatementItem);
    }

    /**
     * 批量删除结算单明细
     * 
     * @param ids 需要删除的结算单明细主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementItemByIds(Long[] ids)
    {
        return busStatementItemMapper.deleteBusStatementItemByIds(ids);
    }

    /**
     * 删除结算单明细信息
     * 
     * @param id 结算单明细主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementItemById(Long id)
    {
        return busStatementItemMapper.deleteBusStatementItemById(id);
    }

    /**
     * 结算单明细保存
     * @param vo
     * @return
     */
    @Override
    @Transactional
    public int itemSave(BusStatementItemVO vo) {
        // 合理化参数验证
        if(vo == null){
            throw new RuntimeException("非法参数");
        }
        if(vo.getDiscountAmount() == null || vo.getItemList() == null){
            throw new RuntimeException("非法参数");
        }
        if(vo.getItemList().size() <= 0){
            throw new RuntimeException("请至少添加一条明细项");
        }
        // 这些明细项一定都指向同一个结算单，所以我们任意取一条的结算单 ID 即可。
        Long statementId = vo.getItemList().get(0).getStatementId();
        // 结算单状态必须是消费中才可以点击保存按钮
        BusStatement statement = statementService.selectBusStatementById(statementId);
        if (statement == null) {
            throw new RuntimeException("非法参数");
        }
        if(BusStatement.STATUS_PAID.equals(statement.getStatus())){
            throw new RuntimeException("已支付的结算单不能进行保存操作");
        }
        // 前台传递的数据都有可能被篡改过，所以我们都需要验证。所以总金额、总数量、我们需要重新计算
        // 定义总金额和总数量
        BigDecimal totalAmount = new BigDecimal("0");
        BigDecimal totalQuantity = new BigDecimal("0");
        BigDecimal discountAmount = vo.getDiscountAmount();
        // 计算总金额和总数量
        for (BusStatementItem item : vo.getItemList()) {
            // 计算总金额
            totalAmount = totalAmount.add(item.getItemPrice().multiply(new BigDecimal(item.getItemQuantity())));
            // 计算总数量
            totalQuantity = totalQuantity.add(new BigDecimal(item.getItemQuantity()));
            // busStatementItemMapper.insertBusStatementItem(item);
        }
        // 对金额进行合理化校验  优惠价格 >=0  &&  总价格 >= 0     优惠价格 <= 总金额
        if(!(totalAmount.compareTo(new BigDecimal(0)) >= 0
            && discountAmount.compareTo(new BigDecimal(0)) >= 0
            && discountAmount.compareTo(totalAmount) <= 0)){
            throw new RuntimeException("非法参数");
        }
        // 每次点击保存时，我们都需要将老的数据都删除掉然后再进行插入。
        busStatementItemMapper.deleteBusStatementItemByStatementId(statementId);
        // 可以优化为批量插入结算单明细对象
        busStatementItemMapper.insertBusStatementItemBatch(vo.getItemList());
        // 更新结算单对象
        return statementService.updateAmountAndQuantity(statementId,totalAmount,totalQuantity,discountAmount);
    }

    /**
     * 结算单支付功能
     * @param vo
     * @return
     */
    @Override
    @Transactional
    public int pay(BusStatementItemVO vo) {
        if (vo == null) {
            throw new RuntimeException("非法参数");
        }
        // 必须先保存后才可以进行支付
        this.itemSave(vo);
        // 若调用上述方法后，那么保存中已经对参数和状态进行了验证。
        // 修改我们的结算单状态
        Long statementId = vo.getItemList().get(0).getStatementId();
        // 获取收款人ID（当前登录用户的 ID）
        Long payId = SecurityUtils.getUserId();

        // 判断当前用户是否是预约用户
        BusStatement statement = statementService.selectBusStatementById(statementId);
        if(statement.getAppointmentId() != null){
            // 是预约用户，需要将其状态也改为已支付（因为这样他是关联了我们结算单的）
            appointmentService.updateStatusById(statement.getAppointmentId(), BusAppointment.STATUS_PAID);
        }
        // 修改结算单状态
        return statementService.updateStatusById(statementId,payId,new Date(),BusStatement.STATUS_PAID);
    }
}
